package com.lifang.framework.context.annotation;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.lifang.framework.annotation.beans.Component;
import com.lifang.framework.annotation.beans.PostConstruct;
import com.lifang.framework.annotation.beans.PreDestroy;
import com.lifang.framework.annotation.beans.Scope;
import com.lifang.framework.beans.factory.config.ConfigurableBeanFactory;
import com.lifang.framework.beans.factory.support.BeanDefinition;
import com.lifang.framework.context.AnnotationParser;

import java.lang.reflect.Method;
import java.util.Arrays;

public class CommonAnnotationParser implements AnnotationParser {

    @Override
    public BeanDefinition parser(Class<?> aClass) {
        Assert.isTrue(aClass.isAnnotationPresent(Component.class), "class {} not implements annotation component", aClass.getName());
        Component component = aClass.getAnnotation(Component.class);
        BeanDefinition definition = new BeanDefinition(aClass);

        Object scopeObj = AnnotationUtil.getAnnotationValue(aClass, Scope.class, "value");
        if (scopeObj != null) {
            String scopeValue = scopeObj.toString();
            Assert.isTrue(Arrays.asList(ConfigurableBeanFactory.SCOPE_PROTOTYPE, ConfigurableBeanFactory.SCOPE_SINGLETON).contains(scopeValue),
                    "'{}' existence unknown scope type", aClass.getSimpleName());
            definition.setScope(scopeValue);
        }

        String beanName = StrUtil.isBlank(component.value()) ? StrUtil.lowerFirst(aClass.getSimpleName()) : component.value();
        definition.setBeanClassName(beanName);
        for (Method method : aClass.getDeclaredMethods()) {
            if (method.isAnnotationPresent(PostConstruct.class)) {
                definition.setInitMethodName(method.getName());
            } else if (method.isAnnotationPresent(PreDestroy.class)) {
                definition.setDestroyMethodName(method.getName());
            }
        }
        return definition;
    }
}
